package com.kmxd.ams.app.event.catalog.command;

import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.kmxd.ams.client.archive.IArchiveRuleCatalogSvc;
import com.kmxd.ams.client.archive.IArchiveTypeSvc;
import com.kmxd.ams.client.archive.vo.ArchiveTypeVO;
import com.kmxd.ams.client.event.catalog.CatalogArchNodeEditEvent;
import com.kmxd.ams.client.event.catalog.CatalogArchNodeRemoveEvent;
import com.kmxd.ams.core.common.enums.CatalogTypeEnum;
import com.kmxd.ams.core.util.IdUtil;
import com.kmxd.ams.core.util.SecurityUtil;
import com.kmxd.ams.infra.archive.entity.ArchiveRuleCatalog;
import com.kmxd.ams.infra.archive.entity.ArchiveType;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.springframework.stereotype.Component;

/**
 * count arch number
 *
 * @author nickbi
 */
@Slf4j
@RequiredArgsConstructor
@Component
public class CatalogCmd {
  private final IArchiveTypeSvc archiveTypeSvc;
  private final IArchiveRuleCatalogSvc archiveRuleCatalogSvc;

  public void changeArchName(CatalogArchNodeEditEvent event) {
    ArchiveTypeVO view = archiveTypeSvc.view(event.getArchTypeId());
    if (ObjectUtil.isEmpty(view)) {
      return;
    }
    ArchiveRuleCatalog one =
        archiveRuleCatalogSvc.getOne(
            Wrappers.<ArchiveRuleCatalog>lambdaQuery()
                .eq(ArchiveRuleCatalog::getType, CatalogTypeEnum.ARCH_NODE.getCode())
                .eq(ArchiveRuleCatalog::getArchTypeId, view.getId())
                .last(" limit 1"));
    if (ObjectUtil.isEmpty(one)) {
      return;
    }
    String name = one.getName();
    if (CharSequenceUtil.equals(view.getName(), name)) {
      return;
    }
    archiveRuleCatalogSvc.update(
        Wrappers.<ArchiveRuleCatalog>lambdaUpdate()
            .eq(ArchiveRuleCatalog::getType, CatalogTypeEnum.ARCH_NODE.getCode())
            .eq(ArchiveRuleCatalog::getArchTypeId, view.getId())
            .set(ArchiveRuleCatalog::getName, view.getName()));
  }

  public void archTypeRemove(CatalogArchNodeRemoveEvent event) {
    String ids = event.getIds();
    if (CharSequenceUtil.isBlank(ids)) {
      return;
    }
    Set<Long> idSet = IdUtil.split(ids);

    Long cropId = SecurityUtil.getCropId(event.getSaToken());
    Long fondsId = SecurityUtil.getFondsId(event.getSaToken());

    List<ArchiveRuleCatalog> catalogList =
        archiveRuleCatalogSvc.list(
            Wrappers.<ArchiveRuleCatalog>lambdaQuery()
                .eq(ArchiveRuleCatalog::getComId, cropId)
                .eq(ArchiveRuleCatalog::getFondsId, fondsId));
    if (ObjectUtil.isEmpty(catalogList)) {
      return;
    }

    List<ArchiveRuleCatalog> archCatalogList =
        catalogList.stream()
            .filter(item -> idSet.contains(item.getArchTypeId()))
            .collect(Collectors.toList());
    if (ObjectUtil.isEmpty(archCatalogList)) {
      return;
    }
    List<ArchiveRuleCatalog> subNodeList = Lists.newArrayList();
    getSubNodeList(catalogList, archCatalogList, subNodeList);
    if (ObjectUtil.isNotEmpty(subNodeList)) {
      archCatalogList.addAll(subNodeList);
    }
    String removeIds =
        archCatalogList.stream()
            .map(item -> String.valueOf(item.getId()))
            .collect(Collectors.joining(","));
    archiveRuleCatalogSvc.remove(removeIds);
  }

  private static void getSubNodeList(
      List<ArchiveRuleCatalog> catalogList,
      List<ArchiveRuleCatalog> archCatalogList,
      List<ArchiveRuleCatalog> subNodeList) {
    Set<Long> parentIdSet =
        archCatalogList.stream().map(ArchiveRuleCatalog::getId).collect(Collectors.toSet());
    List<ArchiveRuleCatalog> subList =
        catalogList.stream()
            .filter(item -> parentIdSet.contains(item.getPid()))
            .collect(Collectors.toList());
    if (ObjectUtil.isNotEmpty(subList)) {
      subNodeList.addAll(subList);
      getSubNodeList(catalogList, subList, subNodeList);
    }
  }
}
